﻿#pragma once
#include <memory>
#include <QObject>
#include <QModbusDevice>
#include <QModbusDataunit>
#include <QQueue>

class QModbusTcpClient;
class QTimer;
class ModbusEvent;
class QElapsedTimer;

class ModbusClient : public QObject {
	Q_OBJECT
public:
	ModbusClient(ModbusEvent* client, QObject* parent = nullptr);
	ModbusClient(ModbusClient const&) = delete;
	ModbusClient& operator=(ModbusClient const&) = delete;
	virtual ~ModbusClient();
	void setConnect(QString const& host, quint16 port);
	bool connectToServer();
	void setTimeout(int timeout);
	void setDevice(int id);
	void onMessage(QByteArray const& bytes);
	QVariant connectionParameter(QModbusDevice::ConnectionParameter parameter) const;
signals:
	void connected();
	void disconnected();
	void connectClosed();
	void suspectNetwork(int level);
	void reportLogs(QString const&,int);
private slots:
	void catchError(QModbusDevice::Error error);
	void stateChanged(QModbusDevice::State state);
	void reConnect();
	void updateModbus();
	void setSuspectDisconnect(bool isDisconnect);
private:
	int m_deviceID = -1;
	QString m_host;
	quint16 m_port = 0;
	QModbusTcpClient* m_modbus;
	QTimer* m_timer = nullptr;
	QTimer* m_reConnectTimer = nullptr;
	ModbusEvent* m_client = nullptr;
	QQueue<QModbusDataUnit> m_sendMsg;
	QModbusDataUnit m_lastWrite;
	std::unique_ptr<QElapsedTimer> m_elapsedTimer;
	int m_reConnectCount = 0;
	int m_requestErrorCount = 0;
	int m_lastRequestErrorCount = 0;
	bool m_isSuspectDisconnect = false;
	bool m_isUnConnected = true;
};
